﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion


#region Usings

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Surface.Presentation.Input;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.UI.View.Converter;
using ScrumTable.UI.View.Util;
using ScrumTable.UI.View.WinTouch.Util;
using ScrumTable.UI.ViewModel;

#endregion

namespace ScrumTable.UI.View.WinTouch.UserControls
{
  

    /// <summary>
    /// Interaction logic for AddButton.xaml
    /// </summary>
    public partial class ValueSelector
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------


        /// <summary>
        /// DependencyProperty for Values.
        /// </summary>
        public static readonly DependencyProperty DomainMetaProperty =
            DependencyProperty.Register("DomainMeta",
                                        typeof(IDomainMeta),
                                        typeof(ValueSelector),
                                        new UIPropertyMetadata(null, OnPropertySet));
        /// <summary>
        /// Gets or sets the values for the menu
        /// </summary>
        /// <value>menu entries.</value>
        public IDomainMeta DomainMeta
        {
            get { return (IDomainMeta)GetValue(DomainMetaProperty); }
            set { SetValue(DomainMetaProperty, value); }
        }


        /// <summary>
        /// DependencyProperty for Values.
        /// </summary>
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem",
                                        typeof(IScrumItemViewModel<DomainBase>),
                                        typeof(ValueSelector),
                                        new UIPropertyMetadata(null, OnPropertySet));
        /// <summary>
        /// Gets or sets the values for the menu
        /// </summary>
        /// <value>menu entries.</value>
        public IScrumItemViewModel<DomainBase> SelectedItem
        {
            get { return (IScrumItemViewModel<DomainBase>)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// Initializes a new instance of the <see cref="AddButton"/> class.
        /// </summary>
        public ValueSelector()
        {
            InitializeComponent();
            ClipToBounds = false;
        }
        #endregion


        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        private static void OnPropertySet(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            var selector = ((ValueSelector)(sender));
            if (selector.DomainMeta != null && selector.SelectedItem != null)
            {
                Binding binding = new Binding { Source = selector.SelectedItem, Path = new PropertyPath("["+selector.DomainMeta.Name+"]") };
                selector.label.SetBinding(ContentProperty, binding);
            }
        }

        private void OnMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var menu = ElementMenuAsScatterItem.AddNewElement(this, Selector);
            menu.Loaded += (senderLoaded, b) => ((FrameworkElement)senderLoaded).RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left) { RoutedEvent = Mouse.MouseDownEvent, Source = this, });
            e.Handled = true;
        }

        private void OnTouchDown(object sender, TouchEventArgs e)
        {
            var menu = ElementMenuAsScatterItem.AddNewElement(this, Selector);
            menu.Loaded += (senderLoaded, b) => ((FrameworkElement)senderLoaded).RaiseEvent(new TouchEventArgs(e.TouchDevice, e.Timestamp) { RoutedEvent = TouchDownEvent, Source = this, });
            e.Handled = true;
        }

        #endregion

        #region ElementMenuAsScatterItem
        /// <summary>
        /// This class represents a ElementMenu wich open himself on the topmost layer on the appscreen. 
        /// </summary>
        private class ElementMenuAsScatterItem : ElementMenu
        {
            private readonly ScatterViewItem _parent;
            private readonly ValueSelector _selector;

            protected override DependencyObject GetContainerForItemOverride()
            {
                var container = new ElementMenuItem();
                container.Click += OnElementMenuItemClick;
                return container;
            }


            private ElementMenuAsScatterItem(ScatterViewItem parent, ValueSelector selector)
            {
                _parent = parent;
                _selector = selector;

                SubmenuClosed += OnSubmenuClosed;
                if (_parent != null)
                {
                    _parent.Unloaded += OnParentMove;
                    _parent.ManipulationStarted += OnParentMove;
                    _parent.ManipulationStarting += OnParentMove;
                    _parent.ContainerManipulationDelta += OnParentMove;
                    _parent.SizeChanged += OnParentMove;
                }
            }

            internal static FrameworkElement AddNewElement(ValueSelector selector, FrameworkElement relativeTo)
            {
                
                ScatterViewItem parentItem = ViewElementUtils.FindVisualParent<ScatterViewItem>(selector);
                ElementMenu menu = new ElementMenuAsScatterItem(parentItem, selector){ActivationMode  = ElementMenuActivationMode.AlwaysActive};
                
                menu.ItemTemplate = selector.Resources["Hierarchical"] as HierarchicalDataTemplate;

                ConverterAllowedValuesToElementMenuItems converter = new ConverterAllowedValuesToElementMenuItemsBack();
                if(selector.DomainMeta.Name=="State")
                {
                    converter.FilterAction = selector.SelectedItem.CanChangeStateTo;
                }
                BindingUtil.BindSourcePath(menu, ItemsSourceProperty, "DomainMeta.SuggestedValues", selector, converter, mode: BindingMode.OneWay);

                ScatteredViewOpener.SetsRotatedPositionOnScatterItem(parentItem, menu, relativeTo, new Point(relativeTo.ActualWidth / 2 - 40 - 12, relativeTo.ActualHeight / 2 - 40 - 12), ((AppScreen)Application.Current.MainWindow).IsRotated);
                ((AppScreen)(Application.Current.MainWindow)).AddItem(menu, false);
                  return menu;
            }


            private void RemoveElement()
            {
                ((AppScreen)(Application.Current.MainWindow)).RemoveItem(this);
                if (_parent != null)
                {
                    _parent.Unloaded -= OnParentMove;
                    _parent.ManipulationStarted -= OnParentMove;
                    _parent.ManipulationStarting -= OnParentMove;
                    _parent.ContainerManipulationDelta -= OnParentMove;
                    _parent.SizeChanged -= OnParentMove;
                }
            }

            private void OnElementMenuItemClick(object sender, RoutedEventArgs e)
            {
                object header;
                if (e.OriginalSource is ElementMenuItem)
                {
                    header = ((ElementMenuItem) e.OriginalSource).Header;
                }
                else
                {
                    header = ((ElementMenuItem) sender).Header;
                }
                if( header is ElementMenuHierarchical)
                {
                    ElementMenuHierarchical elementMenuHierarchical = (ElementMenuHierarchical) header;
                    if (elementMenuHierarchical.Element.Count == 0)
                    {
                        _selector.SelectedItem[_selector.DomainMeta.Name] = elementMenuHierarchical.Value;
                    }
                }
                else
                {
                    _selector.SelectedItem[_selector.DomainMeta.Name] = header;
                }
            }

            

            private void OnSubmenuClosed(object sender, RoutedEventArgs e)
            {
                if (!IsSubmenuOpen)
                {
                    RemoveElement();
                }
            }

            private void OnParentMove(object sender, EventArgs e)
            {
                RemoveElement();
            }

            
        }
        #endregion


    }
}
